#include <cstdint>
#include <functional>
#include <iostream>
#include <unistd.h>
#include <unordered_map>
#include <vector>
#include <memory>
using namespace std;
using TaskFunc = function<void()>;
using RealseFunc = function<void()>;
class TimerTask // 定时器任务类
{
    private:
        uint64_t _id; // 标记任务的id
        uint32_t _time; // 超时的时间
        bool _canceled; // 是否取消了任务
        TaskFunc _task;
        RealseFunc _realse;
    public:
        TimerTask(uint64_t id, uint32_t time, const TaskFunc& func)
            :_id(id), _time(time), _task(func), _canceled(false) {}
        ~TimerTask() {
            if(!_canceled) {
                _task();
            }
            _realse();
        }
        void Cancel() {
            _canceled = true;
        }
        void SetRealse(const RealseFunc& func) {
            _realse = func;
        }
        uint32_t GetTime() {
            return _time;
        }
};
class TimerWheel // 时间轮机制
{
    private:
        using WeakTask = weak_ptr<TimerTask>;
        using SharedTask = shared_ptr<TimerTask>;
        int _tick;
        int _capacity;
        vector<vector<SharedTask>> _wheel;
        unordered_map<uint64_t, WeakTask> _timers;
    private:
        void RemoveTimer(uint64_t id) {
            auto it = _timers.find(id);
            if(it != _timers.end()) {
                _timers.erase(it);
            }
        }
    public:
        TimerWheel()
            :_capacity(60), _tick(0), _wheel(_capacity) {}
        void TimeAdd(uint64_t id, uint32_t time, const TaskFunc& func) // 添加定时任务
        {
            SharedTask st(new TimerTask(id, time, func));
            st->SetRealse(bind(&TimerWheel::RemoveTimer, this, id));
            int pos = (_tick + time) % _capacity;
            _wheel[pos].push_back(st);
            _timers[id] = WeakTask(st);
        }
        void TimerRefresh(uint64_t id) {
            auto it = _timers.find(id);
            if(it == _timers.end()) {
                return ;
            }
            SharedTask st = it->second.lock();
            int t = st->GetTime();
            int index = (_tick + t) % _capacity;
            _wheel[index].push_back(st);
        }
        void TimeCancel(uint64_t id) {
            auto it = _timers.find(id);
            if(it == _timers.end()) {
                return;
            }
            SharedTask st = it->second.lock();
            if(st) {
                st->Cancel();
            }
        } 
        void RunTimerTask() {
            _wheel[_tick].clear();
            _tick = (_tick + 1) % _capacity;
        }
};
class Test {
    public:
        Test() {
            cout << "我是构造函数！" << endl;
        }
        ~Test() {
            cout << "我是析构函数！" << endl;
        }
};
void DelTest(Test* t) {
    delete t;
}
int main() {
    TimerWheel tw;
    Test* t = new Test();
    tw.TimeAdd(666, 5, bind(DelTest, t));
    for(int i = 0; i < 5; i++) {
        sleep(1);
        tw.TimerRefresh(666);
        tw.RunTimerTask();
        cout << "刷新一下了定时任务，在下一个5秒销毁！" << endl;
    }
    // tw.TimeCancel(666);
    while (1) {
        sleep(1);
        cout << "----------------------------" << endl;
        tw.RunTimerTask();
    }
    return 0;
}